/**
 * NODE二进制插件堆栈丢失  eg:$FS.readFile()
 * @param back function 要执行的函数(扩展包)
 * @return function  back.apply(this, args)
 */
$.track = function(back){
	return !$._track ? back : function(...args){
		let T={}, v; Error.captureStackTrace(T);
		try{ v = back.apply(this, args); }
		catch(err){ $.__track(err, T); }
		if(!(v instanceof Promise)) return v;
		return v.catch(err=>$.__track(err,T));
	};
};
$._track = $._track??true; // [配置]是否启用捕获
$.track.ks=(m,s)=>s.forEach(k=>m[k]=$.track(m[k]));
Object.defineProperty($,'__track',{
	value: function(err, s){
		if(err===0) throw 0; //0:用于中断,忽略
		let E=err instanceof $.err, track;
		if(!E && !(err instanceof Error)){
			const opx={fix:2,rtn:true}; E=true;
			err = $.err('$.track', err, opx);
		}
		s = $.stack(1, s.stack); //提前取得的堆栈信息
		if(!(track=$.stack(0,err.stack))) track=s;
		else if(!track.endsWith(s)){ //堆栈拼接(塌陷)
			const P='\n    at ', AF=track.split(P);
			let AL=s.split(P), n=AF.lastIndexOf(AL[1]);
			if(n<0) track+=s; else{
				const x = P+AF.slice(n).join(P);
				if(!s.startsWith(x+P)) track += s;
				else{
					AL = AL.slice(AF.length-n+1);
					track = track+P+AL.join(P);
				}
			}
		}
		if(!E) err.stack = err.message+track;
		else{
			err.__err.fix=track; s=err.stack.split(' ');
			err.stack = s[0]+' '+err.txt(true,true);
		}
		throw err;
	},
});
